package com.star.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.star.exception.ServiceException;
import com.star.exception.SystemException;
import com.star.result.API;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 退出处理器
 *
 * @author tanyapeng
 * @date 2021/3/7
 */
@Slf4j
public class TokenLogoutHandler implements LogoutHandler {

    private TokenManager tokenManager;

    private StringRedisTemplate stringRedisTemplate;

    public TokenLogoutHandler(TokenManager tokenManager, StringRedisTemplate stringRedisTemplate) {
        this.tokenManager = tokenManager;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        try {
            //1 从header里面获取token
            String token = request.getHeader("token");
            log.info("token==========,{}", token);
            if (token == null) {
                throw new ServiceException(20001, "token不存在,退出失败");
            }
            //2 token不为空，移除token，从redis删除token
            tokenManager.removeToken(token);
            // 从token获取用户名
            String username = tokenManager.getUserInfoFromToken(token);
            removeToken(username);
            ObjectMapper mapper = new ObjectMapper();
            mapper.writeValue(response.getWriter(), API.ok("退出成功"));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("logout error - {},{}", ExceptionUtils.getStackTrace(e), request);
            throw new SystemException(10001, "退出登录出错");
        }
    }

    /**
     * 在redis里删除token
     *
     * @param username
     * @return
     */
    private void removeToken(String username) {
        try {
            stringRedisTemplate.delete(username);
        } catch (Exception e) {
            log.error("removeToken error - {},{},{}", ExceptionUtils.getStackTrace(e), username);
            throw new SystemException(10002, "删除token出错");
        }
    }
}
